#include "connectionmanager.h"
#include <QSettings>
#include <QDateTime>
#include <QCryptographicHash>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
#include <QHostAddress>
#include <QRegularExpression>

ConnectionManager::ConnectionManager(QObject *parent)
    : QObject(parent)
    , m_settings(new QSettings("SshTool", "SshTool", this))
{
    // 生成加密密钥
    QByteArray hash = QCryptographicHash::hash("SshToolKey", QCryptographicHash::Sha256);
    m_encryptionKey = hash.left(16); // 使用前16字节作为密钥

    // 加载设置
    loadSettings();
}

ConnectionManager::~ConnectionManager()
{
    saveSettings();
}

bool ConnectionManager::saveProfile(const ConnectionProfile &profile)
{
    if (!validateProfile(profile)) {
        return false;
    }

    // 生成ID（如果需要）
    QString profileId = profile.id.isEmpty() ? generateProfileId() : profile.id;
    ConnectionProfile saveProfile = profile;
    saveProfile.id = profileId;

    // 加密密码
    if (!saveProfile.password.isEmpty()) {
        saveProfile.password = encryptPassword(saveProfile.password);
    }

    // 保存到设置
    m_settings->beginGroup("Profiles");
    m_settings->setValue(profileId, serializeProfile(saveProfile));
    m_settings->endGroup();

    // 更新内存
    m_profiles[profileId] = saveProfile;

    emit profileAdded(saveProfile);
    return true;
}

bool ConnectionManager::updateProfile(const ConnectionProfile &profile)
{
    if (!validateProfile(profile) || profile.id.isEmpty()) {
        return false;
    }

    // 加密密码
    ConnectionProfile updateProfile = profile;
    if (!updateProfile.password.isEmpty()) {
        updateProfile.password = encryptPassword(updateProfile.password);
    }

    // 保存到设置
    m_settings->beginGroup("Profiles");
    m_settings->setValue(profile.id, serializeProfile(updateProfile));
    m_settings->endGroup();

    // 更新内存
    m_profiles[profile.id] = updateProfile;

    emit profileUpdated(updateProfile);
    return true;
}

bool ConnectionManager::deleteProfile(const QString &profileId)
{
    if (!m_profiles.contains(profileId)) {
        return false;
    }

    // 从设置中删除
    m_settings->beginGroup("Profiles");
    m_settings->remove(profileId);
    m_settings->endGroup();

    // 从内存中删除
    m_profiles.remove(profileId);

    emit profileDeleted(profileId);
    return true;
}

ConnectionManager::ConnectionProfile ConnectionManager::getProfile(const QString &profileId) const
{
    return m_profiles.value(profileId);
}

QList<ConnectionManager::ConnectionProfile> ConnectionManager::getAllProfiles() const
{
    return m_profiles.values();
}

QList<ConnectionManager::ConnectionProfile> ConnectionManager::getProfilesByGroup(const QString &group) const
{
    QList<ConnectionProfile> result;
    for (const ConnectionProfile &profile : m_profiles) {
        if (profile.group == group) {
            result.append(profile);
        }
    }
    return result;
}

QList<ConnectionManager::ConnectionProfile> ConnectionManager::getFavoriteProfiles() const
{
    QList<ConnectionProfile> result;
    for (const ConnectionProfile &profile : m_profiles) {
        if (profile.isFavorite) {
            result.append(profile);
        }
    }
    return result;
}

QList<ConnectionManager::ConnectionProfile> ConnectionManager::getRecentProfiles(int limit) const
{
    QList<ConnectionProfile> result = m_profiles.values();
    // 按最后连接时间排序
    std::sort(result.begin(), result.end(), [](const ConnectionProfile &a, const ConnectionProfile &b) {
        return a.lastConnected > b.lastConnected;
    });

    if (result.size() > limit) {
        result = result.mid(0, limit);
    }

    return result;
}

QString ConnectionManager::quickConnect(const QString &host, int port, const QString &username, const QString &password)
{
    ConnectionProfile profile;
    profile.name = QString("%1@%2").arg(username).arg(host);
    profile.host = host;
    profile.port = port;
    profile.username = username;
    profile.password = password;
    profile.group = "Quick Connect";
    profile.isFavorite = false;

    if (saveProfile(profile)) {
        return profile.id;
    }
    return QString();
}

ConnectionManager::ConnectionProfile ConnectionManager::createQuickProfile(const QString &host, int port, const QString &username, const QString &password)
{
    ConnectionProfile profile;
    profile.name = QString("%1@%2").arg(username).arg(host);
    profile.host = host;
    profile.port = port;
    profile.username = username;
    profile.password = password;
    profile.group = "Quick Connect";
    profile.isFavorite = false;

    return profile;
}

QStringList ConnectionManager::getGroups() const
{
    QSet<QString> groups;
    for (const ConnectionProfile &profile : m_profiles) {
        if (!profile.group.isEmpty()) {
        groups.insert(profile.group);
    }
    }
    return QStringList(groups.values());
}

bool ConnectionManager::createGroup(const QString &group)
{
    if (group.isEmpty()) {
        return false;
    }
    return true; // 组是动态创建的
}

bool ConnectionManager::renameGroup(const QString &oldGroup, const QString &newGroup)
{
    if (oldGroup.isEmpty() || newGroup.isEmpty() || oldGroup == newGroup) {
        return false;
    }

    // 更新所有相关配置文件
    for (const QString &profileId : m_profiles.keys()) {
        if (m_profiles[profileId].group == oldGroup) {
            ConnectionProfile profile = m_profiles[profileId];
            profile.group = newGroup;
            updateProfile(profile);
        }
    }

    return true;
}

bool ConnectionManager::deleteGroup(const QString &group)
{
    if (group.isEmpty()) {
        return false;
    }

    // 删除组中的所有配置文件或将其移动到"Ungrouped"
    for (const QString &profileId : m_profiles.keys()) {
        if (m_profiles[profileId].group == group) {
            ConnectionProfile profile = m_profiles[profileId];
            profile.group = "Ungrouped";
            updateProfile(profile);
        }
    }

    return true;
}

bool ConnectionManager::addToGroup(const QString &profileId, const QString &group)
{
    if (!m_profiles.contains(profileId)) {
        return false;
    }

    ConnectionProfile profile = m_profiles[profileId];
    profile.group = group;
    return updateProfile(profile);
}

bool ConnectionManager::removeFromGroup(const QString &profileId)
{
    return addToGroup(profileId, "Ungrouped");
}

QList<ConnectionManager::ConnectionProfile> ConnectionManager::searchProfiles(const QString &keyword) const
{
    QList<ConnectionProfile> result;
    QString lowerKeyword = keyword.toLower();

    for (const ConnectionProfile &profile : m_profiles) {
        if (profile.name.toLower().contains(lowerKeyword) ||
            profile.host.toLower().contains(lowerKeyword) ||
            profile.username.toLower().contains(lowerKeyword) ||
            profile.description.toLower().contains(lowerKeyword)) {
            result.append(profile);
        }
    }

    return result;
}

QList<ConnectionManager::ConnectionProfile> ConnectionManager::searchProfiles(const QString &host, const QString &username) const
{
    QList<ConnectionProfile> result;

    for (const ConnectionProfile &profile : m_profiles) {
        if (profile.host == host && profile.username == username) {
            result.append(profile);
        }
    }

    return result;
}

bool ConnectionManager::importProfiles(const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        return false;
    }

    QByteArray data = file.readAll();
    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (!doc.isArray()) {
        return false;
    }

    QJsonArray array = doc.array();
    for (const QJsonValue &value : array) {
        if (value.isObject()) {
            QJsonObject obj = value.toObject();
            ConnectionProfile profile;
            profile.name = obj["name"].toString();
            profile.host = obj["host"].toString();
            profile.port = obj["port"].toInt();
            profile.username = obj["username"].toString();
            profile.password = obj["password"].toString();
            profile.privateKeyPath = obj["privateKeyPath"].toString();
            profile.group = obj["group"].toString();
            profile.description = obj["description"].toString();
            profile.isFavorite = obj["isFavorite"].toBool();

            saveProfile(profile);
        }
    }

    return true;
}

bool ConnectionManager::exportProfiles(const QString &filePath, const QList<QString> &profileIds)
{
    QJsonArray array;

    QList<ConnectionProfile> profilesToExport;
    if (profileIds.isEmpty()) {
        profilesToExport = getAllProfiles();
    } else {
        for (const QString &profileId : profileIds) {
            if (m_profiles.contains(profileId)) {
                profilesToExport.append(m_profiles[profileId]);
            }
        }
    }

    for (const ConnectionProfile &profile : profilesToExport) {
        QJsonObject obj;
        obj["name"] = profile.name;
        obj["host"] = profile.host;
        obj["port"] = profile.port;
        obj["username"] = profile.username;
        obj["password"] = ""; // 不导出密码
        obj["privateKeyPath"] = profile.privateKeyPath;
        obj["group"] = profile.group;
        obj["description"] = profile.description;
        obj["isFavorite"] = profile.isFavorite;

        array.append(obj);
    }

    QJsonDocument doc(array);
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly)) {
        return false;
    }

    file.write(doc.toJson());
    return true;
}

bool ConnectionManager::exportProfileAsJson(const QString &profileId, const QString &filePath)
{
    QList<QString> profileIds;
    profileIds.append(profileId);
    return exportProfiles(filePath, profileIds);
}

void ConnectionManager::addToHistory(const ConnectionHistory &history)
{
    m_history.prepend(history);

    // 限制历史记录大小
    if (m_history.size() > 1000) {
        m_history = m_history.mid(0, 1000);
    }

    emit historyAdded(history);
}

QList<ConnectionManager::ConnectionHistory> ConnectionManager::getConnectionHistory(const QString &profileId) const
{
    if (profileId.isEmpty()) {
        return m_history;
    }

    QList<ConnectionHistory> result;
    for (const ConnectionHistory &history : m_history) {
        if (history.profileId == profileId) {
            result.append(history);
        }
    }

    return result;
}

QList<ConnectionManager::ConnectionHistory> ConnectionManager::getRecentHistory(int limit) const
{
    if (m_history.size() <= limit) {
        return m_history;
    }

    return m_history.mid(0, limit);
}

bool ConnectionManager::clearHistory(const QString &profileId)
{
    if (profileId.isEmpty()) {
        m_history.clear();
    } else {
        for (int i = m_history.size() - 1; i >= 0; i--) {
            if (m_history[i].profileId == profileId) {
                m_history.removeAt(i);
            }
        }
    }

    return true;
}

bool ConnectionManager::clearAllHistory()
{
    m_history.clear();
    return true;
}

QMap<QString, QVariant> ConnectionManager::getStatistics() const
{
    QMap<QString, QVariant> stats;

    int totalConnections = 0;
    int successfulConnections = 0;
    QMap<QString, int> hostCounts;
    QString mostUsedHost;
    int maxHostCount = 0;

    for (const ConnectionHistory &history : m_history) {
        totalConnections++;
        if (history.successful) {
            successfulConnections++;
        }

        QString host = getProfile(history.profileId).host;
        if (!host.isEmpty()) {
            hostCounts[host]++;
            if (hostCounts[host] > maxHostCount) {
                maxHostCount = hostCounts[host];
                mostUsedHost = host;
            }
        }
    }

    stats["totalConnections"] = totalConnections;
    stats["successfulConnections"] = successfulConnections;
    stats["successRate"] = totalConnections > 0 ? (successfulConnections * 100.0 / totalConnections) : 0;
    stats["mostUsedHost"] = mostUsedHost;
    stats["totalProfiles"] = m_profiles.size();
    stats["favoriteProfiles"] = getFavoriteProfiles().size();

    return stats;
}

int ConnectionManager::getTotalConnections() const
{
    return m_history.size();
}

int ConnectionManager::getSuccessfulConnections() const
{
    int count = 0;
    for (const ConnectionHistory &history : m_history) {
        if (history.successful) {
            count++;
        }
    }
    return count;
}

QString ConnectionManager::getMostUsedHost() const
{
    QMap<QString, int> hostCounts;
    for (const ConnectionHistory &history : m_history) {
        QString host = getProfile(history.profileId).host;
        if (!host.isEmpty()) {
            hostCounts[host]++;
        }
    }

    QString mostUsedHost;
    int maxCount = 0;
    for (const QString &host : hostCounts.keys()) {
        if (hostCounts[host] > maxCount) {
            maxCount = hostCounts[host];
            mostUsedHost = host;
        }
    }

    return mostUsedHost;
}

QMap<QString, int> ConnectionManager::getConnectionStatsByDay() const
{
    QMap<QString, int> stats;

    for (const ConnectionHistory &history : m_history) {
        QString date = history.connectedTime.toString("yyyy-MM-dd");
        stats[date]++;
    }

    return stats;
}

QString ConnectionManager::encryptPassword(const QString &password) const
{
    // 简单的XOR加密（实际应用中应该使用更安全的加密方法）
    QByteArray data = password.toUtf8();
    for (int i = 0; i < data.size(); i++) {
        data[i] = data[i] ^ m_encryptionKey[i % m_encryptionKey.size()];
    }
    return QString::fromLatin1(data.toBase64());
}

QString ConnectionManager::decryptPassword(const QString &encrypted) const
{
    // 简单的XOR解密
    QByteArray data = QByteArray::fromBase64(encrypted.toLatin1());
    for (int i = 0; i < data.size(); i++) {
        data[i] = data[i] ^ m_encryptionKey[i % m_encryptionKey.size()];
    }
    return QString::fromUtf8(data);
}

bool ConnectionManager::validateProfile(const ConnectionProfile &profile) const
{
    // 基本设置验证
    if (profile.name.isEmpty()) {
        return false;
    }

    if (profile.host.isEmpty()) {
        return false;
    }

    if (profile.port <= 0 || profile.port > 65535) {
        return false;
    }

    if (profile.username.isEmpty()) {
        return false;
    }

    // 认证方法验证
    if (profile.password.isEmpty() && profile.privateKeyPath.isEmpty()) {
        return false;
    }

    return true;
}

bool ConnectionManager::validateHost(const QString &host) const
{
    return isValidHostAddress(host);
}

bool ConnectionManager::validatePort(int port) const
{
    return isValidPortNumber(port);
}

bool ConnectionManager::validateUsername(const QString &username) const
{
    return isValidUsername(username);
}

void ConnectionManager::loadSettings()
{
    m_settings->beginGroup("Profiles");
    QStringList profileIds = m_settings->childKeys();

    m_profiles.clear();
    for (const QString &profileId : profileIds) {
        m_profiles[profileId] = profileFromSettings(profileId);
    }

    m_settings->endGroup();

    // 加载历史记录
    m_settings->beginGroup("History");
    int historySize = m_settings->beginReadArray("connections");
    m_history.clear();

    for (int i = 0; i < historySize; i++) {
        m_settings->setArrayIndex(i);
        ConnectionHistory history;
        history.profileId = m_settings->value("profileId").toString();
        history.profileName = m_settings->value("profileName").toString();
        history.connectedTime = m_settings->value("connectedTime").toDateTime();
        history.disconnectedTime = m_settings->value("disconnectedTime").toDateTime();
        history.duration = m_settings->value("duration").toString();
        history.successful = m_settings->value("successful").toBool();
        history.errorMessage = m_settings->value("errorMessage").toString();

        m_history.append(history);
    }

    m_settings->endArray();
    m_settings->endGroup();

    // 清理旧的历史记录
    cleanupOldHistory();

    emit settingsChanged();
}

void ConnectionManager::saveSettings()
{
    m_settings->beginGroup("Profiles");
    // 清除旧的配置
    m_settings->remove("");

    // 保存新的配置
    for (const QString &profileId : m_profiles.keys()) {
        m_settings->setValue(profileId, serializeProfile(m_profiles[profileId]));
    }

    m_settings->endGroup();

    // 保存历史记录
    m_settings->beginGroup("History");
    m_settings->beginWriteArray("connections", m_history.size());

    for (int i = 0; i < m_history.size(); i++) {
        m_settings->setArrayIndex(i);
        const ConnectionHistory &history = m_history[i];
        m_settings->setValue("profileId", history.profileId);
        m_settings->setValue("profileName", history.profileName);
        m_settings->setValue("connectedTime", history.connectedTime);
        m_settings->setValue("disconnectedTime", history.disconnectedTime);
        m_settings->setValue("duration", history.duration);
        m_settings->setValue("successful", history.successful);
        m_settings->setValue("errorMessage", history.errorMessage);
    }

    m_settings->endArray();
    m_settings->endGroup();
}

void ConnectionManager::resetSettings()
{
    m_settings->clear();
    m_profiles.clear();
    m_history.clear();
    loadSettings();
}

QString ConnectionManager::generateProfileId() const
{
    return QString::number(QDateTime::currentMSecsSinceEpoch()) + "-" + QString::number(qrand());
}

QString ConnectionManager::settingsKey(const QString &key) const
{
    return "ConnectionManager/" + key;
}

ConnectionManager::ConnectionProfile ConnectionManager::profileFromSettings(const QString &profileId) const
{
    QVariant data = m_settings->value(profileId);
    return deserializeProfile(data.toString());
}

void ConnectionManager::profileToSettings(const ConnectionProfile &profile)
{
    m_settings->setValue(profile.id, serializeProfile(profile));
}

QString ConnectionManager::serializeProfile(const ConnectionProfile &profile) const
{
    QJsonObject obj;
    obj["id"] = profile.id;
    obj["name"] = profile.name;
    obj["host"] = profile.host;
    obj["port"] = profile.port;
    obj["username"] = profile.username;
    obj["password"] = profile.password;
    obj["privateKeyPath"] = profile.privateKeyPath;
    obj["description"] = profile.description;
    obj["group"] = profile.group;
    obj["lastConnected"] = profile.lastConnected.toString(Qt::ISODate);
    obj["connectCount"] = profile.connectCount;
    obj["isFavorite"] = profile.isFavorite;

    QJsonDocument doc(obj);
    return doc.toJson(QJsonDocument::Compact);
}

ConnectionManager::ConnectionProfile ConnectionManager::deserializeProfile(const QString &data) const
{
    ConnectionProfile profile;

    QJsonDocument doc = QJsonDocument::fromJson(data.toUtf8());
    if (doc.isObject()) {
        QJsonObject obj = doc.object();
        profile.id = obj["id"].toString();
        profile.name = obj["name"].toString();
        profile.host = obj["host"].toString();
        profile.port = obj["port"].toInt();
        profile.username = obj["username"].toString();
        profile.password = obj["password"].toString();
        profile.privateKeyPath = obj["privateKeyPath"].toString();
        profile.description = obj["description"].toString();
        profile.group = obj["group"].toString();
        profile.lastConnected = QDateTime::fromString(obj["lastConnected"].toString(), Qt::ISODate);
        profile.connectCount = obj["connectCount"].toInt();
        profile.isFavorite = obj["isFavorite"].toBool();
    }

    return profile;
}

void ConnectionManager::cleanupOldHistory()
{
    // 只保留最近30天的历史记录
    QDateTime cutoff = QDateTime::currentDateTime().addDays(-30);

    for (int i = m_history.size() - 1; i >= 0; i--) {
        if (m_history[i].connectedTime < cutoff) {
            m_history.removeAt(i);
        }
    }
}

QString ConnectionManager::formatDuration(const QDateTime &start, const QDateTime &end) const
{
    qint64 seconds = start.secsTo(end);
    if (seconds < 60) {
        return QString("%1s").arg(seconds);
    } else if (seconds < 3600) {
        return QString("%1m %2s").arg(seconds / 60).arg(seconds % 60);
    } else {
        return QString("%1h %2m").arg(seconds / 3600).arg((seconds % 3600) / 60);
    }
}

bool ConnectionManager::isValidHostAddress(const QString &host) const
{
    if (host.isEmpty()) {
        return false;
    }

    // 检查是否是有效的IP地址或主机名
    QHostAddress address;
    if (address.setAddress(host)) {
        return true;
    }

    // 检查主机名格式
    QRegularExpression regex("^[a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?)*$");
    return regex.match(host).hasMatch();
}

bool ConnectionManager::isValidPortNumber(int port) const
{
    return port > 0 && port <= 65535;
}

bool ConnectionManager::isValidUsername(const QString &username) const
{
    if (username.isEmpty()) {
        return false;
    }

    // 用户名通常只包含字母、数字、下划线和连字符
    QRegularExpression regex("^[a-zA-Z0-9_\\-]+$");
    return regex.match(username).hasMatch();
}

